package util

import (
	"crypto/hmac"
	xsha1 "crypto/sha1"
	"crypto/sha512"
	"encoding/base64"
	"fmt"
	"io"

	"github.com/micro-plat/lib4go/security/aes"
	"github.com/micro-plat/lib4go/security/des"
	"github.com/micro-plat/lib4go/security/md5"
	"github.com/micro-plat/lib4go/security/rsa"
	"github.com/micro-plat/lib4go/security/sha1"
	"github.com/micro-plat/lib4go/security/sha256"
)

//MD5 生成字符串md5
func MD5(str string) string {
	return md5.Encrypt(str)
}

//AESEncrypt aes加密
func AESEncrypt(content, key string, mode ...string) (res string, err error) {
	keyBytes := []byte(key)
	var iv = keyBytes[:16]
	return aes.EncryptByte(key, []byte(content), iv, mode...)
}

//AESDecrypt aes解密
func AESDecrypt(content, key string, mode ...string) (res string, err error) {
	keyBytes := []byte(key)
	var iv = keyBytes[:16]
	return aes.DecryptByte(key, []byte(content), iv, mode...)
}

//DESEncrypt des加密
func DESEncrypt(input string, skey string, mode ...string) (r string, err error) {
	return des.Encrypt(input, skey, mode...)
}

// DESDecrypt DES解密
func DESDecrypt(input string, skey string, mode ...string) (r string, err error) {
	return des.Decrypt(input, skey, mode...)
}

//Sha1Encrypt Sha1加密
func Sha1Encrypt(raw string) string {
	return sha1.Encrypt(raw)
}

//Sha256Encrypt Sha256加密
func Sha256Encrypt(raw string) string {
	return sha256.Encrypt(raw)
}

//Sha512Encrypt Sha512加密
func Sha512Encrypt(raw string) string {
	h := sha512.New()
	io.WriteString(h, raw)
	return fmt.Sprintf("%x", h.Sum(nil))
}

//HmacEncrypt HMAC加密
func HmacEncrypt(data, key string) string {
	mac := hmac.New(xsha1.New, []byte(key))
	mac.Write([]byte(data))
	expectedMAC := mac.Sum(nil)
	return base64.StdEncoding.EncodeToString(expectedMAC)
}

//RSAEncrypt RSA公钥加密
func RSAEncrypt(origData, publicKey, pkcsType string) (data string, err error) {
	return rsa.Encrypt(origData, publicKey, pkcsType)
}

//RSADecrypt RSA私钥解密
func RSADecrypt(origin, key, pkcsType string) (string, error) {
	return rsa.Decrypt(origin, key, pkcsType)
}

//RSASign RSA签名
func RSASign(message, privateKey, mode, pkcsType string) (string, error) {
	return rsa.Sign(message, privateKey, mode, pkcsType)
}

//RSASignVerify RSA签名验证
func RSASignVerify(src, sign, publicKey, mode, pkcsType string) (pass bool, err error) {
	return rsa.Verify(src, sign, publicKey, mode, pkcsType)
}
